﻿@namespace BootstrapBlazor.Components
@typeparam TValue
@inherits BootstrapComponentBase

@if(IsLoaded)
{
    if (Data != null && ChildContent != null)
    {
        @ChildContent(Data)
    }
    else
    {
        <Empty />
    }
}
else
{
    if (LoadingContent == null)
    {
        <div class="async-render">
            <Spinner Color="Color.Primary" Size="Size" />
        </div>
    }
    else
    {
        @LoadingContent
    }
}

@code {
    /// <summary>
    /// 加载结果
    /// </summary>
    private TValue? Data { get; set; }

    /// <summary>
    /// 保存的触发值
    /// </summary>
    private object? LastValue { get; set; }

    /// <summary>
    /// 是否加载完毕
    /// </summary>
    private bool IsLoaded { get; set; } = false;

    /// <summary>
    /// 获得 / 设置 Spinner 大小 默认 None 无设置
    /// </summary>
    [Parameter]
    public Size Size { get; set; }

    /// <summary>
    /// 获得/设置 是否显示此 AsyncRender 重新渲染的对照值
    /// </summary>
    [Parameter]
    public object? TriggerValue { get; set; }

    /// <summary>
    /// 获得/设置 异步加载数据方法
    /// </summary>
    [Parameter]
    public Func<Task<TValue>>? OnQueryAsync { get; set; }

    /// <summary>
    /// 获得/设置 异步加载数据后方法
    /// </summary>
    [Parameter]
    public Func<TValue?, Task>? OnAfterQueryAsync { get; set; }

    /// <summary>
    /// 获得/设置 异步加载数据后方法
    /// </summary>
    [Parameter]
    public Action<TValue?>? OnAfterQuery { get; set; }

    /// <summary>
    /// 获得/设置 子组件内容
    /// </summary>
    [Parameter]
    public RenderFragment<TValue>? ChildContent { get; set; }

    /// <summary>
    /// 获得/设置 加载时显示内容，默认为Spinner
    /// </summary>
    [Parameter]
    public RenderFragment? LoadingContent { get; set; }

    /// <summary>
    /// OnParametersSetAsync 方法
    /// </summary>
    /// <returns></returns>
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        if (firstRender)
        {
            ReRender();
        }

        if (LastValue != TriggerValue)
        {
            LastValue = TriggerValue;
            ShowLoading();
            ReRender();
        }
    }

    /// <summary>
    /// 显示加载动画
    /// </summary>
    private void ShowLoading()
    {
        IsLoaded = false;
        StateHasChanged();
    }

    /// <summary>
    /// 重新渲染
    /// </summary>
    private async void ReRender()
    {
        if (OnQueryAsync != null)
        {
            Data = await OnQueryAsync();
            IsLoaded = true;
            LastValue = TriggerValue;
            if (OnAfterQuery != null)
            {
                OnAfterQuery(Data);
            }
            if (OnAfterQueryAsync != null)
            {
                await OnAfterQueryAsync(Data);
            }
            StateHasChanged();
        }
    }
}
